// Copyright 2022 The Molego Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package config

import (
	"encoding/xml"

	. "gitee.com/west0207/molego/core/log"
	utils "gitee.com/west0207/molego/core/utils"

	etree "gitee.com/west0207/etree"
)

// <property name="date" value="datetime" dbms="mysql" />
type Property struct {
	Name  string `xml:"name,attr"`
	Value string `xml:"value,attr"`
	Dbms  string `xml:"dbms,attr"`
}

// <include file="classpath:db/app01/db-app01-ddl.xml" />
type Include struct {
	File string `xml:"file,attr"`
}

// entry-xxxx-app01.xml
// <databaseChangeLog ..>
// 	<property name="date" value="datetime" dbms="mysql" />
// 	...
// 	<include file="classpath:db/app01/db-app01-ddl.xml" />
// 	...
// </databaseChangeLog>
type EntryXml struct {
	XMLName    xml.Name   `xml:"databaseChangeLog"`
	Properties []Property `xml:"property"`
	Include    []Include  `xml:"include"`
}

// 本地保留一份配置实例供全局使用
var EntryXmlConfig EntryXml

// 获取entry入口文件配置
// xmlFile *string 入口文件名称
func GetEntryXmlConfig(xmlFile *string) (EntryXml, error) {
	EntryXmlConfig = EntryXml{Properties: nil, Include: nil}

	fileBytes, err := utils.GetFileBytes(xmlFile)
	if err != nil {
		// 获取文件%v的字节数组失败
		Sug.Errorf("Failed to get byte array of file %v，error: %v", *xmlFile, err)
		panic(err)
	}

	err = xml.Unmarshal(fileBytes, &EntryXmlConfig)
	if err != nil {
		// 解析文件%v失败
		Sug.Errorf("Failed to parse file %v，error: %v", *xmlFile, err)
		panic(err)
	}
	// fmt.Printf("XMLName: %#v\n", v.XMLName)
	// fmt.Printf("Properties: %#v\n", v.Properties)
	// fmt.Printf("Include: %#v\n", v.Include)
	return EntryXmlConfig, nil
}

// 获取一个changeSetXml配置文件中全部changeSet
// changeSetXmlFile string changeSetXmlFile文件名称
func GetChangeSets(changeSetXmlFile string) ([]*etree.Element, error) {
	xmlDoc := etree.NewDocument()
	if err := xmlDoc.ReadFromFile(changeSetXmlFile); err != nil {
		panic(err)
	}
	root := xmlDoc.SelectElement("databaseChangeLog")
	return root.ChildElements(), nil
}
